// useCallback
// 作用：在组件多次重新渲染的时候缓存函数，跟useMemo相似，useMemo是缓存值，useCallback是缓存函数

import { memo, useCallback, useState } from "react"



// memo包裹的Input组件，保证在props发生变化时才渲染，
// 但是但传递的prop是函数时，函数是引用类型，父组件一更新渲染就会产生一个新函数引用传给子组件，
// 而子组件接收到的新函数引用跟旧函数引用比较不相等，因此触发子组件更新渲染
// 解决方案：使用useCallback把函数缓存

const Input1 = memo(function Input ({ onChange }) {
  console.log('子组件Input1重新渲染了')
  return <input type="text" onChange={(e) => onChange(e.target.value)} />
})

const Input2 = memo(function Input ({ onChange }) {
  console.log('子组件Input2重新渲染了')
  return <input type="text" onChange={(e) => onChange(e.target.value)} />
})

function App05 () {
  // 传给子组件的函数，未使用useCallback缓存，父组件更新会触发子组件更新
  const changeHandler1 = (value) => console.log(value)
  // 传给子组件的函数，使用了useCallback缓存，父组件更新不会触发子组件更新
  const changeHandler2 = useCallback((value) => console.log(value), [])
  // 触发父组件重新渲染的函数
  const [count, setCount] = useState(0)
  return (
    <div className="App">
      {/* 把函数作为prop传给子组件 */}
      <Input1 onChange={changeHandler1} /><br/>
      <Input2 onChange={changeHandler2} /><br/>

      {/* 点击修改count会引发父组件更新渲染 */}
      <button onClick={() => setCount(count + 1)}>{count}</button>
    </div>
  )
}

export default App05
